<?php
require_once('src/service/BaseService.php');
require_once('src/Utils.php');

require_once('src/vo/FlagVO.php');
require_once('src/vo/EventVO.php');
require_once('src/vo/GameVO.php');
require_once('src/vo/PlayerVO.php');
 
class YabzsService extends BaseService {

  /* --- STATS --- */

  // cached 
  public function getStatsForAllGames() {  
        
     if ($this->cache->isInCache(Cache::$STATS_FOR_ALL_GAMES_KEY)) {
        return $this->cache->getFromCache(Cache::$STATS_FOR_ALL_GAMES_KEY); 
     }
     
     $games = $this->getAllGames();
     $allPlayers = $this->getAllPlayers();
     $flags = $this->getAllFlags();
     
     $statsList = array();

     foreach($games as $game) {
        $localStats = $this->getStatsForGame($game->id);
        array_push($statsList, $localStats);
     }  
     
     $stats = $this->statsParser->aggregateStats($statsList, $allPlayers, $flags);
     $stats->totalGames = $this->getTotalGamesCount();

     return $stats;  
  }  
  
  public function getStatsForGameRange($startId, $endId) {  
     
     $games = $this->getGamesFromGameRange($startId, $endId);
     $players = $this->getPlayersFromGameRange($startId, $endId);
     $flags = $this->getAllFlags();
     
     $statsList = array();

     foreach($games as $game) {
        $localStats = $this->getStatsForGame($game->id);
        array_push($statsList, $localStats);
     }  
     
     $stats = $this->statsParser->aggregateStats($statsList, $players, $flags);
     $stats->totalGames = count($statsList);

     return $stats;  
  }  
  
  public function getStatsForDateRange($startDate, $endDate) {          
     $startDate = date("Y-m-d", strtotime($startDate));      
     $endDate = date("Y-m-d", strtotime($endDate));

     $games = $this->getGamesFromDateRange($startDate, $endDate);
     $players = $this->getPlayersFromDateRange($startDate, $endDate);
     $flags = $this->getAllFlags();
     
     $statsList = array();

     foreach($games as $game) {
        $localStats = $this->getStatsForGame($game->id);
        array_push($statsList, $localStats);
     }  
     
     $stats = $this->statsParser->aggregateStats($statsList, $players, $flags);
     $stats->totalGames = count($statsList);

     return $stats;  
  }     
    
  public function getStatsForGame($game_id) {   
     $events = $this->getEventsForGame($game_id);
     $players = $this->getPlayersForGame($game_id);
     $flags = $this->getAllFlags();
          
     $stats = $this->statsParser->parseStats($events, $players, $flags);

     return $stats;  
  }
  
  // cached
  public function getStatsForLastGame() {   
  
     if ($this->cache->isInCache(Cache::$STATS_FOR_LAST_GAME_KEY)) {
        return $this->cache->getFromCache(Cache::$STATS_FOR_LAST_GAME_KEY); 
     }  
  
     $game = $this->getLastGame(); 
     $result = $this->getStatsForGame($game->id);   
     return $result;       
  }
  
  /* --- KILLRATIO --- */  
  
  // cached
  public function getKillratioDataForAllGames($useSkipCount = false) {
   
      if ($useSkipCount == TRUE) {
        if ($this->cache->isInCache(Cache::$KILLRATIO_FOR_ALL_GAMES_ADJUSTED_KEY)) {
           return $this->cache->getFromCache(Cache::$KILLRATIO_FOR_ALL_GAMES_ADJUSTED_KEY); 
        }          
      }
      else {
        if ($this->cache->isInCache(Cache::$KILLRATIO_FOR_ALL_GAMES_KEY)) {
           return $this->cache->getFromCache(Cache::$KILLRATIO_FOR_ALL_GAMES_KEY); 
        }    
      }
     
      $events = $this->getAllEvents();
      $players = $this->getAllPlayers();
      $flags = $this->getAllFlags();
  
      $result = $this->statsParser->parseKillratioGraphData($events, $players, $flags, $useSkipCount);
  
      return $result;
  }    
  
  public function getKillratioDataForGameRange($startId, $endId, $useSkipCount = false) {     
      $events = $this->getEventsFromGameRange($startId, $endId);
      $players = $this->getPlayersFromGameRange($startId, $endId);
      $flags = $this->getAllFlags();
  
      $result = $this->statsParser->parseKillratioGraphData($events, $players, $flags, $useSkipCount);
  
      return $result;
  }   
  
  public function getKillratioDataForDateRange($startDate, $endDate, $useSkipCount = false) {              
      $startDate = date("Y-m-d", strtotime($startDate));      
      $endDate = date("Y-m-d", strtotime($endDate));

      $events = $this->getEventsFromDateRange($startDate, $endDate);
      $players = $this->getPlayersFromDateRange($startDate, $endDate);
      $flags = $this->getAllFlags();
  
      $result = $this->statsParser->parseKillratioGraphData($events, $players, $flags, $useSkipCount);
  
      return $result;
  }    
     
  
  public function getKillratioDataForGame($game_id) {   
      $events = $this->getEventsForGame($game_id);
      $players = $this->getPlayersForGame($game_id);
      $flags = $this->getAllFlags();
    
      $result = $this->statsParser->parseKillratioGraphData($events, $players, $flags, false);
  
      return $result;
  }  
  
  // cached
  public function getKillratioDataForLastGame() {   
  
     if ($this->cache->isInCache(Cache::$KILLRATIO_FOR_LAST_GAME_KEY)) {
        return $this->cache->getFromCache(Cache::$KILLRATIO_FOR_LAST_GAME_KEY); 
     }    
  
     $game = $this->getLastGame(); 
     $result = $this->getKillratioDataForGame($game->id);   
     return $result;       
  }  
         
  
  /* --- GAMES --- */  

  // cached
  public function getAllGames() {
  
     if ($this->cache->isInCache(Cache::$ALL_GAMES_KEY)) {
        return $this->cache->getFromCache(Cache::$ALL_GAMES_KEY); 
     }      
  
     $games = Doctrine::getTable('GAMES')->findAll();
     $result = $this->transformObjectsToVO($games, "GameVO");    
     return $result;  
  } 
  
  private function getGamesFromGameRange($startId, $endId) {
     $q = Doctrine_Query::create()
     ->select('*')
     ->from('GAMES g')
     ->where('g.id >= ? AND g.id <= ?', array($startId, $endId));

     $games = $q->execute();        
     $result = $this->transformObjectsToVO($games, "GameVO");    
     return $result;  
  }     

  private function getGamesFromDateRange($startDate, $endDate) {     
     if (!Utils::isDate($startDate) || !Utils::isDate($endDate)) {     
        return NULL;
     }    

     $q = Doctrine_Query::create()
     ->select('*')
     ->from('GAMES g')
     ->where('g.datetime BETWEEN ? AND ?', array($startDate, $endDate));

     $games = $q->execute();        
     $result = $this->transformObjectsToVO($games, "GameVO");    
     return $result;  
  } 
  
  private function getLastGame() {
      $q = Doctrine_Query::create()
      ->select('*')
      ->from('GAMES g')
      ->orderBy("g.id DESC");
     
     $result = $q->fetchOne();          
     $game = new GameVO();
     $game->updateFromObject($result);     
       
     return $game; 
  }  

  // cached
  public function getTotalGamesCount() {
  
     if ($this->cache->isInCache(Cache::$TOTAL_GAMES_COUNT_KEY)) {
        return $this->cache->getFromCache(Cache::$TOTAL_GAMES_COUNT_KEY); 
     }    
  
     $q = Doctrine_Query::create()
    ->select('COUNT(*)')
    ->from('GAMES');

     $result = $q->execute(array(), Doctrine::HYDRATE_SINGLE_SCALAR);
     return (int) $result;
  } 
  
  /* --- FLAGS --- */
  
  // cached
  public function getAllFlags() {   
     
     if ($this->cache->isInCache(Cache::$ALL_FLAGS_KEY)) {
        return $this->cache->getFromCache(Cache::$ALL_FLAGS_KEY); 
     }    
  
     $flags = Doctrine::getTable('FLAGS')->findAll();
     $result = $this->transformObjectsToVO($flags, "FlagVO");    
     return $result;  
  }
  
  /* --- EVENTS --- */

  private function getAllEvents() {
     // doctrine is so fucking slow   
     // $events = Doctrine::getTable('EVENTS')->findAll();    
     // $result = $this->transformObjectsToVO($events, "EventVO");     

      $pdo = $this->conn->getDbh();
      $q = 'SELECT * from EVENTS';           
      $events = $pdo->query($q)->fetchAll();
      $result = $this->transformArrayToVO($events, "EventVO");
        
      return $result;  
  }     
  
  private function getEventsFromGameRange($startId, $endId) {
      if (!is_numeric($startId) || !is_numeric($endId)) {
        return NULL;
      }
     
      $pdo = $this->conn->getDbh();
      $q = 'SELECT * from EVENTS e WHERE e.game_id >= '.$startId.' AND e.game_id <= '.$endId;           
      $events = $pdo->query($q)->fetchAll();
      $result = $this->transformArrayToVO($events, "EventVO");
        
      return $result;  
  }   

  private function getEventsFromDateRange($startDate, $endDate) {
      if (!Utils::isDate($startDate) || !Utils::isDate($endDate)) {     
         return NULL;
      }   
                                                  
      $q = Doctrine_Query::create()
      ->select('*')
      ->from('EVENTS e')
      ->where('e.datetime BETWEEN ? AND ?', array($startDate, $endDate));

      $events = $q->execute();
      $result = $this->transformObjectsToVO($events, "EventVO");
        
      return $result;  
  }      
     
  private function getEventsForGame($game_id) {   
      $gameId = $game_id;
      
      if (!is_numeric($gameId)) {
        return NULL;
      }

     $q = Doctrine_Query::create()
      ->select('*')
      ->from('EVENTS e')
      ->WHERE("e.game_id = ?", $gameId);

     $events = $q->execute();
     $result = $this->transformObjectsToVO($events, "EventVO");    
     return $result;  
  }    


  /* --- PLAYERS --- */
    
  // cached  
  public function getAllPlayers() {
  
     if ($this->cache->isInCache(Cache::$ALL_PLAYERS_KEY)) {
        return $this->cache->getFromCache(Cache::$ALL_PLAYERS_KEY); 
     }  
  
     $players = Doctrine::getTable('PLAYERS')->findAll();    
     $result = $this->transformObjectsToVO($players, "PlayerVO");    
     return $result;  
  }     
  
  
  private function getPlayersFromGameRange($startId, $endId) {      
      if (!is_numeric($startId) || !is_numeric($endId)) {
        return NULL;
      }

      $pdo = $this->conn->getDbh();
      $q = 'SELECT id, name from PLAYERS p WHERE p.id in ('.
           'SELECT DISTINCT e.player_id FROM EVENTS e WHERE e.game_id >= '.$startId.' AND e.game_id <= '.$endId.
           ' UNION '. 
           'SELECT DISTINCT e.target_id FROM EVENTS e WHERE e.game_id >= '.$startId.' AND e.game_id <= '.$endId.')';
           
      $result = $pdo->query($q)->fetchAll();
      $result = $this->transformArrayToVO($result, "PlayerVO");    
      return $result;     
  }     
      
  private function getPlayersFromDateRange($startDate, $endDate) {      
      if (!Utils::isDate($startDate) || !Utils::isDate($endDate)) {     
         return NULL;
      }   

      $pdo = $this->conn->getDbh();
      $q = 'SELECT id, name from PLAYERS p WHERE p.id in ('.
           'SELECT DISTINCT e.player_id FROM EVENTS e WHERE e.datetime BETWEEN "'.$startDate.'" AND "'.$endDate.'"
            UNION '. 
           'SELECT DISTINCT e.target_id FROM EVENTS e WHERE e.datetime BETWEEN "'.$startDate.'" AND "'.$endDate.'")';

      $result = $pdo->query($q)->fetchAll();
      $result = $this->transformArrayToVO($result, "PlayerVO");    
      return $result;     
  }     

  private function getPlayersForGame($game_id) {    
      $gameId = $game_id;
      
      if (!is_numeric($gameId)) {
        return NULL;
      }

      $pdo = $this->conn->getDbh();
      $q = 'SELECT id, name from PLAYERS p WHERE p.id in ('.
           'SELECT DISTINCT e.player_id FROM EVENTS e WHERE e.game_id = '.$gameId.
           ' UNION '. 
           'SELECT DISTINCT e.target_id FROM EVENTS e WHERE e.game_id = '.$gameId.')';
           
      $result = $pdo->query($q)->fetchAll();
      $result = $this->transformArrayToVO($result, "PlayerVO");    
      return $result; 
  }     
  
  /* --- CACHE --- */
  
  public function recreateCache() {
      $this->cache->putInCache(Cache::$ALL_PLAYERS_KEY, $this->getAllPlayers());
      $this->cache->putInCache(Cache::$ALL_FLAGS_KEY, $this->getAllFlags());
      $this->cache->putInCache(Cache::$ALL_GAMES_KEY, $this->getAllGames());
      $this->cache->putInCache(Cache::$TOTAL_GAMES_COUNT_KEY, $this->getTotalGamesCount());
      $this->cache->putInCache(Cache::$KILLRATIO_FOR_LAST_GAME_KEY, $this->getKillratioDataForLastGame());
      $this->cache->putInCache(Cache::$KILLRATIO_FOR_ALL_GAMES_KEY, $this->getKillratioDataForAllGames(false));
      $this->cache->putInCache(Cache::$KILLRATIO_FOR_ALL_GAMES_ADJUSTED_KEY, $this->getKillratioDataForAllGames(true));
      $this->cache->putInCache(Cache::$STATS_FOR_LAST_GAME_KEY, $this->getStatsForLastGame());
      $this->cache->putInCache(Cache::$STATS_FOR_ALL_GAMES_KEY, $this->getStatsForAllGames());
      $this->cache->setCacheRecreationDate(time());
  }  
  
  public function getCacheRecreationDate() {
      return $this->cache->getCacheRecreationDate();
  }  
       
}
?>